import { defineComponent, PropType } from 'vue';
import { useVJSFContext } from '../context';
import { Schema, SchemaFormPropsDefine } from '../types';
import { isArray } from '../utils';

// 渲染三种的 schame

// staticArray: {
//   type: 'array',
//   items: [
//     {
//       type: 'string',
//     },
//     {
//       type: 'number',
//     },
//   ],
// },
// singleTypeArray: {
//   type: 'array',
//   items: {
//     type: 'object',
//     properties: {
//       name: {
//         type: 'string',
//       },
//       age: {
//         type: 'number',
//       },
//     },
//   },
// },
// multiSelectArray: {
//   type: 'array',
//   items: {
//     type: 'string',
//     enum: ['123', '456', '789'],
//   },
// },

const ArrayItemWrapper = defineComponent({
  name: 'ArrayItemWrapper',
  props: {
    onAdd: {
      type: Function as PropType<(index: number) => void>,
      required: true,
    },
    onDelete: {
      type: Function as PropType<(index: number) => void>,
      required: true,
    },
    onUp: {
      type: Function as PropType<(index: number) => void>,
      required: true,
    },
    onDown: {
      type: Function as PropType<(index: number) => void>,
      required: true,
    },
    index: {
      type: Number as PropType<number>,
      required: true,
    },
  },
  setup(props, { slots }) {
    // 利用一个高阶函数
    const { index } = props;
    const handleAdd = () => props.onAdd(index);
    const handleDelete = () => props.onDelete(index);
    const handleUp = () => props.onUp(index);
    const handleDown = () => props.onDown(index);

    return () => {
      return (
        <div>
          <div>
            <button onClick={handleAdd}>新增</button>
            <button onClick={handleDelete}>删除</button>
            <button onClick={handleUp}>上移</button>
            <button onClick={handleDown}>下移</button>
          </div>
          <div>{slots.default ? slots.default() : null}</div>
        </div>
      );
    };
  },
});

export default defineComponent({
  name: 'ArrayField',
  props: SchemaFormPropsDefine,
  setup(props) {
    const { SchemaItem } = useVJSFContext();

    const handleChange = (v: any, index: number) => {
      const { value } = props;
      const arr = isArray(value) ? value : [];
      if (v) {
        arr[index] = v;
      }
      props.onChange(arr);
    };

    const handleAdd = (index: number) => {
      // 拿到当前 item 的 value
      const { value } = props;
      const arr = isArray(value) ? value : [];
      arr.splice(index + 1, 0, undefined);
      props.onChange(arr);
    };
    const handleDelete = (index: number) => {
      const { value } = props;
      const arr = isArray(value) ? value : [];
      arr.splice(index, 1);
      props.onChange(arr);
    };
    const handleUp = (index: number) => {
      if (index <= 0) return;
      const { value } = props;
      const arr = isArray(value) ? value : [];
      // 先删除当前元素，在插入当前元素的前面一个
      const item = arr.splice(index, 1);
      arr.splice(index - 1, 0, item[0]);
      props.onChange(arr);
    };
    const handleDown = (index: number) => {
      const { value } = props;
      const arr = isArray(value) ? value : [];
      if (index >= arr.length - 1) return;
      const item = arr.splice(index, 1);
      arr.splice(index + 1, 0, item[0]);
      props.onChange(arr);
    };
    return () => {
      const { schema, rootSchema, value } = props;
      const items: Schema[] = schema.items as any;
      // 根据 schema.item 当前的类型判断出要渲染成那种组件
      // 正常的数组 form
      const isMultiType = isArray(schema.items);
      // 下拉框 带选项的 form
      const isSelect = schema.items && (schema.items as any).enum;
      // 不同类型的数据
      const currValue = isArray(value) ? value : [];
      if (isMultiType) {
        return items.map((s: Schema, index: number) => (
          <SchemaItem
            schema={s}
            rootSchema={rootSchema}
            value={currValue[index]}
            onChange={(v: any) => {
              handleChange(v, index);
            }}
          />
        ));
      } else if (isSelect) {
        return <div>hih</div>;
      } else {
        // ;[
        //   { name: "", age: "22" },
        //   { name: "", age: "22" }
        // ]
        return currValue.map((v: any, index: number) => {
          return (
            <ArrayItemWrapper
              onAdd={handleAdd}
              onDelete={handleDelete}
              onUp={handleUp}
              onDown={handleDown}
              index={index}>
              <SchemaItem
                schema={schema.items as Schema}
                rootSchema={rootSchema}
                value={v}
                // onChange 拿到的 value 是一个对象，表示的是当前 item 一组的值
                onChange={(v: any) => {
                  handleChange(v, index);
                }}
              />
            </ArrayItemWrapper>
          );
        });
      }
    };
  },
});
